package com.resifind.www.service.impl;

import com.resifind.www.constant.ErrorCode;
import com.resifind.www.constant.RechargeStatus;
import com.resifind.www.dao.AdminDao;
import com.resifind.www.dao.ClientDao;
import com.resifind.www.dao.MerchantDao;
import com.resifind.www.dao.RecordDao;
import com.resifind.www.dao.impl.AdminDaoImpl;
import com.resifind.www.dao.impl.ClientDaoImpl;
import com.resifind.www.dao.impl.MerchantDaoImpl;
import com.resifind.www.dao.impl.RecordDaoImpl;
import com.resifind.www.exception.BaseException;
import com.resifind.www.exception.Resp;
import com.resifind.www.po.*;
import com.resifind.www.po.Record;
import com.resifind.www.service.AdminService;
import com.resifind.www.service.ClientService;
import com.resifind.www.util.JdbcUtils;

import java.sql.Connection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 36069
 */
public class AdminServiceImpl implements AdminService {
    private final AdminDao adminDao = new AdminDaoImpl();
    private final ClientDao clientDao = new ClientDaoImpl();
    private final MerchantDao merchantDao = new MerchantDaoImpl();
    private final RecordDao recordDao = new RecordDaoImpl();
    private final ClientService clientService = new ClientServiceImpl();

    @Override
    public Resp<String> login(String password) {
        boolean b = adminDao.queryByPassword(password);
        if (b) {
            return Resp.success("success");
        } else {
            throw new BaseException(500, "密码错误");
        }
    }

    @Override
    public Resp<List<Recharge>> queryRecharge(String status) {
        List<Recharge> recharges = adminDao.queryRecharge(status);
        return Resp.success(recharges);
    }

    @Override
    public Resp<String> updateRechargeStatus(int rechargeId, String status) {
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            // 更新充值记录状态
            boolean rechargeResult = adminDao.updateRechargeStatus(rechargeId, status, conn);
            boolean clientResult = true;
            // 如果审核通过，更新用户余额
            if (status.equals(RechargeStatus.APPROVED)) {
                //查询充值记录，获取用户id和充值金额
                Recharge recharge = clientDao.queryRechargeByRechargeId(rechargeId);
                if (recharge != null) {
                    //更新用户余额
                    clientResult = clientDao.updateBalance(recharge.getClientId(), recharge.getAmount(), conn);
                }
            }
            if (rechargeResult && clientResult) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

    @Override
    public Resp<List<Merchant>> getPendingMerchants() {
        List<Merchant> merchants = merchantDao.queryPendingMerchants();
        return Resp.success(merchants);
    }

    @Override
    public Resp<PageBean<Client>> getClientsByPage(int pageNum, int pageSize) {
        List<Client> clients = clientDao.queryClientByPage(pageNum, pageSize);
        int clientCount = clientDao.queryClientCount();
        PageBean<Client> pageBean = new PageBean<>();
        pageBean.setRows(clients);
        pageBean.setTotalCount(clientCount);
        return Resp.success(pageBean);
    }

    @Override
    public Resp<SignInStatistics> getSignInStatistics() {
        List<Client> clients = clientDao.queryAllClients();
        int totalSignInDays = 0;
        int totalContinuousSignInDays = 0;
        int activeClientCount = 0;
        Map<String, Integer> signInDaysDistribution = new LinkedHashMap<>(5);
        //分布范围
        String[] ranges = {"0-3", "4-7", "8-14", "14-30", "31-3650"};
        //初始化分布
        for (String range : ranges) {
            signInDaysDistribution.put(range, 0);
        }
        for (Client client : clients) {
            int totalSign = recordDao.queryTotalDaysByClientId(client.getId());
            //计算总签到天数
            totalSignInDays += totalSign;
            //添加分布
            for (String range : ranges) {
                String[] split = range.split("-");
                int start = Integer.parseInt(split[0]);
                int end = Integer.parseInt(split[1]);
                if (totalSign >= start && totalSign <= end) {
                    signInDaysDistribution.put(range, signInDaysDistribution.getOrDefault(range, 0) + 1);
                    break;
                }
            }
            List<Record> records = recordDao.queryRecordByClientId(client.getId());
            int continuousDays = clientService.calculateContinuousDays(records);
            //计算总连续签到天数
            totalContinuousSignInDays += continuousDays;
            //活跃用户数
            if (continuousDays >= 3) {
                activeClientCount++;
            }
        }
        //平均签到天数（保留两位小数）
        double averageSignInDays = (double) totalSignInDays / clients.size();
        averageSignInDays = Math.round(averageSignInDays * 100) / 100.0;
        //平均连续签到天数（保留两位小数）
        double averageContinuousSignInDays = (double) totalContinuousSignInDays / clients.size();
        averageContinuousSignInDays = Math.round(averageContinuousSignInDays * 100) / 100.0;
        //封装返回对象
        SignInStatistics signInStatistics = new SignInStatistics(averageSignInDays, activeClientCount, averageContinuousSignInDays, signInDaysDistribution);
        return Resp.success(signInStatistics);
    }

    @Override
    public Resp<String> updateClientStatus(int clientId, String status) {
        Connection conn = null;
        try {
            conn = JdbcUtils.getConn();
            JdbcUtils.beginTransaction(conn);
            boolean result = clientDao.updateStatus(clientId, status, conn);
            if (result) {
                JdbcUtils.commitTransaction(conn);
                return Resp.success("success");
            } else {
                JdbcUtils.rollbackTransaction(conn);
                throw new BaseException(ErrorCode.DB_ERROR);
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            JdbcUtils.rollbackTransaction(conn);
            throw new BaseException(ErrorCode.SERVER_ERROR);
        } finally {
            JdbcUtils.closeConn(conn, null, null);
        }
    }

}
